home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / OLE2BOOK.ZIP / CHAP13.ZIP / PATRON / TENANT.CPP < prev    next >
C/C++ Source or Header  |  1993-07-19  |  45KB  |  1,822 lines

  1. /*
  2.  * TENANT.CPP
  3.  * Modifications for Chapter 13
  4.  *
  5.  * Implementation of the CTentant class which holds information
  6.  * for a single object on a page.  It maintains position, references
  7.  * to data, and a storage.
  8.  *
  9.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  10.  *
  11.  * Kraig Brockschmidt, Software Design Engineer
  12.  * Microsoft Systems Developer Relations
  13.  *
  14.  * Internet  :  kraigb@microsoft.com
  15.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  16.  */
  17.  
  18.  
  19. #include "patron.h"
  20.  
  21.  
  22. /*
  23.  * CTenant::CTenant
  24.  * CTenant::~CTenant
  25.  *
  26.  * Constructor Parameters:
  27.  *  dwID            DWORD identifier for this page.
  28.  *  hWnd            HWND of the pages window.
  29.  *  pPG             LPCPages to the parent structure.
  30.  */
  31.  
  32. CTenant::CTenant(DWORD dwID, HWND hWnd, LPCPages pPG)
  33.     {
  34.     m_hWnd=hWnd;
  35.     m_dwID=dwID;
  36.  
  37.     m_fInitialized=0;
  38.     m_pIStorage=NULL;
  39.     m_cOpens=0;
  40.  
  41.     m_pObj=NULL;
  42.     m_pPG =pPG;
  43.  
  44.     m_cRef=0;
  45.     m_pIOleObject=NULL;
  46.     m_pIViewObject=NULL;
  47.  
  48.     m_pIOleClientSite=NULL;
  49.     m_pIAdviseSink=NULL;
  50.  
  51.     m_fLinkAvail=TRUE;          //Checked on FLoad.
  52.  
  53.     //CHAPTER13MOD
  54.     m_pmk=NULL;
  55.     m_pmkFile=NULL;
  56.     //End CHAPTER13MOD
  57.     return;
  58.     }
  59.  
  60.  
  61. CTenant::~CTenant(void)
  62.     {
  63.     //CHAPTER13MOD
  64.     if (NULL!=m_pmk)
  65.         m_pmk->Release();
  66.     //End CHAPTER13MOD
  67.  
  68.     if (NULL!=m_pIViewObject)
  69.         {
  70.         m_pIViewObject->SetAdvise(m_fe.dwAspect, 0, NULL);
  71.         m_pIViewObject->Release();
  72.         }
  73.  
  74.     if (NULL!=m_pIOleObject)
  75.         m_pIOleObject->Release();
  76.  
  77.     //We delete our own interfaces since we control them
  78.     if (NULL!=m_pIAdviseSink)
  79.         delete m_pIAdviseSink;
  80.  
  81.     if (NULL!=m_pIOleClientSite)
  82.         delete m_pIOleClientSite;
  83.  
  84.     if (NULL!=m_pObj)
  85.         {
  86.         //We know we only hold one reference from UCreate or FLoad
  87.         m_pObj->Release();
  88.         m_pObj=NULL;
  89.         }
  90.  
  91.     return;
  92.     }
  93.  
  94.  
  95.  
  96.  
  97. /*
  98.  * CTenant::QueryInterface
  99.  * CTenant::AddRef
  100.  * CTenant::Release
  101.  *
  102.  * Purpose:
  103.  *  IUnknown members for CTenant object.
  104.  */
  105.  
  106. STDMETHODIMP CTenant::QueryInterface(REFIID riid, LPLPVOID ppv)
  107.     {
  108.     *ppv=NULL;
  109.  
  110.     if (IsEqualIID(riid, IID_IUnknown))
  111.         *ppv=(LPVOID)this;
  112.  
  113.     if (IsEqualIID(riid, IID_IOleClientSite))
  114.         *ppv=(LPVOID)m_pIOleClientSite;
  115.  
  116.     if (IsEqualIID(riid, IID_IAdviseSink))
  117.         *ppv=(LPVOID)m_pIAdviseSink;
  118.  
  119.     if (NULL!=*ppv)
  120.         {
  121.         ((LPUNKNOWN)*ppv)->AddRef();
  122.         return NOERROR;
  123.         }
  124.  
  125.     return ResultFromScode(E_NOINTERFACE);
  126.     }
  127.  
  128.  
  129. STDMETHODIMP_(ULONG) CTenant::AddRef(void)
  130.     {
  131.     return ++m_cRef;
  132.     }
  133.  
  134. STDMETHODIMP_(ULONG) CTenant::Release(void)
  135.     {
  136.     ULONG           cRefT;
  137.  
  138.     cRefT=--m_cRef;
  139.  
  140.     if (0L==m_cRef)
  141.         delete this;
  142.  
  143.     return cRefT;
  144.     }
  145.  
  146.  
  147.  
  148.  
  149.  
  150.  
  151. /*
  152.  * CTenant::GetID
  153.  *
  154.  * Return Value:
  155.  *  DWORD           dwID field in this tenant.  This function is only here
  156.  *                  to avoid hiding inline implementations in pages.h
  157.  */
  158.  
  159. DWORD CTenant::GetID(void)
  160.     {
  161.     return m_dwID;
  162.     }
  163.  
  164.  
  165.  
  166.  
  167.  
  168. /*
  169.  * CTenant::GetStorageName
  170.  *
  171.  * Parameters:
  172.  *  pszName         LPSTR to a buffer in which to store the storage name
  173.  *                  for this tenant.
  174.  *
  175.  * Return Value:
  176.  *  UINT            Number of characters stored.
  177.  */
  178.  
  179. UINT CTenant::GetStorageName(LPSTR pszName)
  180.     {
  181.     return wsprintf(pszName, "Tenant %lu", m_dwID);
  182.     }
  183.  
  184.  
  185.  
  186.  
  187.  
  188. /*
  189.  * CTenant::UCreate
  190.  *
  191.  * Purpose:
  192.  *  Creates a new tenant of the given CLSID, which can be either a
  193.  *  static bitmap or metafile now (Chapter 7) and which may eventually
  194.  *  be any OLE object.
  195.  *
  196.  * Parameters:
  197.  *  tType           TENANTTYPE to create, either a static metafile, bitmap,
  198.  *                  or some kind of OLE object (later chapters)
  199.  *                  This determined which OleCreate* call we use.
  200.  *  pvType          LPVOID providing the relevant pointer from which
  201.  *                  to create the tenant, depending on iType.
  202.  *  pFE             LPFORMATETC specifying the type of renderings to use.
  203.  *  pptl            LPPOINTL in which we can store offset coordinates.
  204.  *  pszl            LPSIZEL where this object should store its lometric extents.
  205.  *  pIStorage       LPSTORAGE of the page we live in.  We have to
  206.  *                  create another storage under this for the tenant.
  207.  *  ppo             LPPATRONOBJECT containing placement data.
  208.  *  dwData          DWORD containing extra data, sensitive to iType.
  209.  *
  210.  * Return Value:
  211.  *  UINT            A UCREATE_* value depending on what we actually do.
  212.  */
  213.  
  214. UINT CTenant::UCreate(TENANTTYPE tType, LPVOID pvType, LPFORMATETC pFE
  215.     , LPPOINTL pptl, LPSIZEL pszl, LPSTORAGE pIStorage
  216.     , LPPATRONOBJECT ppo, DWORD dwData)
  217.     {
  218.     HRESULT             hr;
  219.     LPUNKNOWN           pObj;
  220.     UINT                uRet=UCREATE_GRAPHICONLY;
  221.  
  222.     if (NULL==pvType || NULL==pIStorage)
  223.         return UCREATE_FAILED;
  224.  
  225.     //Fail if this is called for an already living tenant.
  226.     if (m_fInitialized)
  227.         return UCREATE_FAILED;
  228.  
  229.     m_fInitialized=TRUE;
  230.  
  231.     //Create a new storage for this tenant.
  232.     if (!FOpen(pIStorage))
  233.         return UCREATE_FAILED;
  234.  
  235.     /*
  236.      * Get the placement info if it's here.  We either have a non-NULL
  237.      * LPPATRONOBJECT in ppo or we have to use default placement and
  238.      * retrieve the size from the object itself.
  239.      */
  240.     pszl->cx=0;
  241.     pszl->cy=0;
  242.  
  243.     if (NULL!=ppo)
  244.         {
  245.         *pFE=ppo->fe;
  246.         *pptl=ppo->ptl;
  247.         *pszl=ppo->szl;     //Could be 0,0 in which case we ask object
  248.  
  249.         uRet=UCREATE_PLACEDOBJECT;
  250.         }
  251.  
  252.     hr=ResultFromScode(E_FAIL);
  253.  
  254.     //Now create an object based specifically for the type.
  255.     switch (tType)
  256.         {
  257.         case TENANTTYPE_NULL:
  258.             break;
  259.  
  260.         case TENANTTYPE_STATIC:
  261.             /*
  262.              * We could use OleCreateStaticFromData here which does
  263.              * pretty much what we're doing below.  However, it does
  264.              * not allow us to control whether we paste a bitmap or
  265.              * a metafile--it uses metafile first, bitmap second.  For
  266.              * this reason we'll use code developed in Chapter 6's
  267.              * FreeLoader to affect the paste.
  268.              */
  269.             hr=CreateStatic((LPDATAOBJECT)pvType, pFE, &pObj);
  270.             break;
  271.  
  272.         case TENANTTYPE_EMBEDDEDOBJECT:
  273.             hr=OleCreate(*((LPCLSID)pvType), IID_IUnknown, OLERENDER_DRAW
  274.                 , NULL, NULL, m_pIStorage, (LPLPVOID)&pObj);
  275.             break;
  276.  
  277.         case TENANTTYPE_EMBEDDEDFILE:
  278.             hr=OleCreateFromFile(CLSID_NULL, (LPSTR)pvType, IID_IUnknown
  279.                 , OLERENDER_DRAW, NULL, NULL, m_pIStorage, (LPLPVOID)&pObj);
  280.             break;
  281.  
  282.         case TENANTTYPE_EMBEDDEDOBJECTFROMDATA:
  283.             hr=OleCreateFromData((LPDATAOBJECT)pvType, IID_IUnknown
  284.                 , OLERENDER_DRAW, NULL, NULL, m_pIStorage, (LPLPVOID)&pObj);
  285.             break;
  286.  
  287.         case TENANTTYPE_LINKEDFILE:
  288.             hr=OleCreateLinkToFile((LPSTR)pvType, IID_IUnknown
  289.                 , OLERENDER_DRAW, NULL, NULL, m_pIStorage, (LPLPVOID)&pObj);
  290.             break;
  291.  
  292.         case TENANTTYPE_LINKEDOBJECTFROMDATA:
  293.             hr=OleCreateLinkFromData((LPDATAOBJECT)pvType, IID_IUnknown
  294.                 , OLERENDER_DRAW, NULL, NULL, m_pIStorage, (LPLPVOID)&pObj);
  295.             break;
  296.  
  297.         default:
  298.             break;
  299.         }
  300.  
  301.     //If creation didn't work, get rid for the element FOpen created.
  302.     if (FAILED(hr))
  303.         {
  304.         Destroy(pIStorage);
  305.         return UCREATE_FAILED;
  306.         }
  307.  
  308.     //We don't get the size if PatronObject data was seen already.
  309.     FObjectInitialize(pObj, pFE, dwData);
  310.  
  311.     //We depend here on m_pIOleObject having been initialized.
  312.     if ((0==pszl->cx && 0==pszl->cy))
  313.         {
  314.         SIZEL   szl;
  315.  
  316.         //Try to get the real size of the object, default to 2"*2"
  317.         SETSIZEL((*pszl), 2*LOMETRIC_PER_INCH, 2*LOMETRIC_PER_INCH);
  318.  
  319.         if (SUCCEEDED(m_pIOleObject->GetExtent